// co
// all/race/allsettle/finnaly
// queue/promisequeue
// requestCache/请求重试
// layzman/flow
// promisify
// promiseLike
// 模拟微任务

function co(g) {
    const gen = g();
    var next = (...args) => {
        const { value, done } = gen.next(...args);
        if (done) return value;
        if (value.then) {
            return value.then(item => next(item))
        }
        return next(value)
    }
    next()
}
// co(function* () {
//     let a = yield Promise.resolve(1);
//     let b = yield Promise.resolve(2);
//     console.log(a + b)
// })

Promise.myAll = (promises) => {
    let res = [];
    let count = 0;
    return new Promise((resolve, reject) => { 
        for (let i = 0; i < promises.length; i++) {
            Promise.resolve(promises[i]).then(item => {
                res[i] = item;
                count++;
                if(count === promises.length){
                    resolve(res)
                }
            }).catch(err => reject(err))
        }
    })
}
Promise.myAll([
    Promise.resolve(1),
    Promise.resolve(2)
]).then((res) => console.log(res))

// 手动执行
class Queue {
    constructor(){
        this.list = [];
    }
    add(fn){
        this.list.push(fn)
        return this;
    }
    async task(){
       for(let i = 0; i< this.list.length; i++){
            await this.list[i]()
       }
    }
}
// const queue = new Queue();
// var delay = (timeout) => new Promise((resolve) => setTimeout(resolve, timeout))
// queue.add(() => delay(1000).then(() => console.log('task 1')))
//     .add(() => delay(2000).then(() => console.log('task 2')))
//     .task();


// 自动执行并限制并发


class LazyMan {
    constructor(){
        this.list = [];
        setTimeout(() => {
            this.next()
        }, 0);
    }
    log(msg){
        let task = () => setTimeout(() => {
            console.log(msg)
            this.next()
        }, 0)
        this.list.push(task);
        return this;
    }
    sleep(time){
        let task = () => setTimeout(() => {
            // console.log(msg)
            this.next()
        }, time)
        this.list.push(task);
        return this;
    }
    next(){
        let task = this.list.shift();
        task && task()
    }
}

// new LazyMan().log('1111').sleep(5000).log('22222')


function flow(promises){
    function next(index){
        let fn = promises[index];
        if(!fn) return;
        let res = fn();
        if(res && res.then){
            res.then(() => next(index + 1))
        } else {
            next(index+1)
        }
    }
    next(0)
}
// const delay = (time) => new Promise(resolve => setTimeout(resolve, time))
// flow([
//     () => console.log('1'),
//     () => console.log('2'),
//     () => delay(1000).then(() => console.log('3')),
//     () => delay(4000).then(() => console.log('4')),
//     () => console.log('5'),
//     () => console.log('6'),
// ])

// 控制并发，并且获取结果，结果方式promiseAll
// flowPromise()







function promisify(fn){
    return (...args) => {
        return new Promise((resolve, reject) => {
            function callback(err, ...res){
                if(err) reject(err)
                resolve(res.length > 1 ? res : res[0])
            }
            fn.call(this, args, callback)
        })
    }
}
